package com.tax.config.filter;

import com.alibaba.fastjson.JSONObject;
import com.tax.common.constant.CommonConstant;
import com.tax.common.util.MD5Util;
import com.tax.common.util.SpringUtils;
import com.tax.common.util.StringsUtil;
import com.tax.config.response.Response;
import com.tax.config.response.ResponseCode;
import com.tax.dto.req.LoginReq;
import com.tax.entity.TdUser;
import com.tax.enums.LoginTypeEnum;
import com.tax.enums.RedisKey;
import com.tax.manager.AccessTokenManager;
import com.tax.service.ITdUserService;
import lombok.extern.slf4j.Slf4j;
import net.logstash.logback.encoder.org.apache.commons.lang.StringUtils;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.concurrent.TimeUnit;

@Slf4j
public class LoginInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        log.info("这里是登录信息拦截处理");
        try {
            LoginReq loginReq = getRequestParams(request);
            if (null == loginReq) {
                doResult(response, ResponseCode.PARA_ERROR.getCode(),"请检查登录信息！");
                return false;
            }
            if (LoginTypeEnum.find(loginReq.getUserLoginType()) == null) {
                doResult(response,ResponseCode.PARA_ERROR.getCode(),"当前登录类型不存在！");
                return false;
            }
            //用户登录信息校验
            if (!verification(loginReq)) {
                doResult(response,ResponseCode.PARA_ERROR.getCode(),"请检查登录信息！");
                return false;
            }
            AbstractApplicationContext context = SpringUtils.getAbstractApplicationContext(request);
            ITdUserService iTdUserService = (ITdUserService)context.getBean(CommonConstant.ITD_USER_SERVICE);
            TdUser tdUser = iTdUserService.selectUserByPhone(loginReq.getTelephone());
            if (null == tdUser) {
                log.error("当前登录用户不存在:{}",JSONObject.toJSONString(loginReq));
                doResult(response,ResponseCode.PARA_ERROR.getCode(),"当前登录用户不存在！");
                return false;
            }
            StringRedisTemplate stringRedisTemplate = (StringRedisTemplate)context.getBean("stringRedisTemplate");
            //验证码登录
            /*if (loginReq.getUserLoginType().equals(CommonConstant.USER_ACCESS_TOKEN_TYPE_VALIDCODE)) {
                String regCodeKey = RedisKey.PHONE_SMS_REG_CODE.getValue(loginReq.getTelephone());
                if (!stringRedisTemplate.hasKey(regCodeKey)) {
                    doResult(response,ResponseCode.PARA_ERROR.getCode(),"验证码不存在，请检查!");
                    return false;
                }
            }*/
            //密码登录
            if (loginReq.getUserLoginType().equals(CommonConstant.USER_ACCESS_TOKEN_TYPE_PASSWORD)) {
                String loginP = MD5Util.getMd5(loginReq.getPasswordHash());
                if (!loginP.equalsIgnoreCase(tdUser.getPassword())) { //密码校验
                    doResult(response,ResponseCode.PARA_ERROR.getCode(),"验证码错误，请检查！");
                    return false;
                }
            }
            AccessTokenManager accessTokenManager = (AccessTokenManager)context.getBean(CommonConstant.ACCESS_TOEKN_MANAGERR);
            tdUser.setUserLoginType(loginReq.getUserLoginType());
            String deviceId = request.getHeader("deviceId");
            String appVersion = request.getHeader("appVersion");
            String appsys = request.getHeader("appsys");
            String token = accessTokenManager.generateToken(tdUser, deviceId, appVersion, appsys);
            String tokenKey = "";
            //验证码登录
            if (loginReq.getUserLoginType().equals(CommonConstant.USER_ACCESS_TOKEN_TYPE_VALIDCODE)) {
                tokenKey = StringsUtil.getUserValidcodeLoginKey(loginReq.getTelephone());
            }
            //密码登录
            if (loginReq.getUserLoginType().equals(CommonConstant.USER_ACCESS_TOKEN_TYPE_PASSWORD)) {
                tokenKey = StringsUtil.getUserPasswordLoginKey(loginReq.getTelephone());
            }

            stringRedisTemplate.opsForValue().set(tokenKey,token,CommonConstant.ACCESS_TOKEN_EXPIRE, TimeUnit.DAYS);
            //登录成功
            /*Map<String,String> data = new HashMap<>();
            data.put("token",token);
            data.put("redirectUrl","");
            doResult(response,ResponseCode.OK.getCode(), null,data);*/
        } catch (Exception e) {
            log.error(e.getMessage());
            doResult(response,ResponseCode.PARA_ERROR.getCode(),e.getMessage());
            return false;
        }
        return true;
    }

    public void doResult(HttpServletResponse response,int code,String message) {
        Response resultResponse = new Response(code,message);
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json; charset=utf-8");
        PrintWriter out = null;
        try {
            out = response.getWriter();
            out.append(JSONObject.toJSONString(resultResponse));
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (out != null) {
                out.close();
            }
        }
    }

    public void doResult(HttpServletResponse response,int code,String message,Object data) {
        Response resultResponse = new Response(code,message,data);
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json; charset=utf-8");
        PrintWriter out = null;
        try {
            out = response.getWriter();
            out.append(JSONObject.toJSONString(resultResponse));
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (out != null) {
                out.close();
            }
        }
    }

    public LoginReq getRequestParams(HttpServletRequest request) throws IOException {
        StringBuffer data = new StringBuffer();
        String line = null;
        BufferedReader reader = null;
        reader = request.getReader();
        while (null != (line = reader.readLine())) {
            data.append(line);
        }
        if (StringUtils.isNotBlank(data.toString())) {
            return JSONObject.parseObject(data.toString(),LoginReq.class);
        }
        return null;
    }


    public boolean verification(LoginReq loginReq) {

        //登录类型
        if (StringUtils.isBlank(loginReq.getUserLoginType())) {
            return false;
        }
        //登录ID
        if (StringUtils.isBlank(loginReq.getTelephone())) {
            return false;
        }
        /*//登录密码
        if (StringUtils.isBlank(loginReq.getPasswordHash())) {
            return false;
        }*/
        return true;
    }
}
